<template>
  <div class="timeline-container">
    <div class="timeline-header" v-if="title">
      <h3 class="text-lg font-semibold">{{ title }}</h3>
    </div>
    <div class="timeline-content">
      <div class="timeline-list">
        <div
          v-for="(item, index) in items"
          :key="item.id || index"
          class="timeline-item"
          :class="{
            'item-success': item.type === 'success',
            'item-warning': item.type === 'warning',
            'item-danger': item.type === 'danger',
            'item-info': item.type === 'info',
            'item-primary': item.type === 'primary'
          }"
        >
          <!-- 时间轴节点 -->
          <div class="timeline-node">
            <div class="node-dot" :class="`dot-${item.type || 'default'}`">
              <Icon v-if="item.icon" :icon="item.icon" class="node-icon" />
              <div v-else class="node-default"></div>
            </div>
            <div v-if="index < items.length - 1" class="node-line"></div>
          </div>

          <!-- 时间轴内容 -->
          <div class="timeline-content-item">
            <div class="content-header">
              <div class="content-title">{{ item.title }}</div>
              <div class="content-time">{{ formatTime(item.time) }}</div>
            </div>
            
            <div class="content-body">
              <div class="content-description" v-if="item.description">
                {{ item.description }}
              </div>
              
              <!-- 操作人信息 -->
              <div class="content-operator" v-if="item.operator">
                <Icon icon="ep:user" class="mr-1" />
                {{ item.operator }}
              </div>

              <!-- 标签 -->
              <div class="content-tags" v-if="item.tags && item.tags.length > 0">
                <el-tag
                  v-for="tag in item.tags"
                  :key="tag.name"
                  :type="tag.type || 'info'"
                  size="small"
                  class="mr-1 mb-1"
                >
                  {{ tag.name }}
                </el-tag>
              </div>

              <!-- 附件 -->
              <div class="content-attachments" v-if="item.attachments && item.attachments.length > 0">
                <div class="attachments-title">
                  <Icon icon="ep:paperclip" class="mr-1" />
                  附件
                </div>
                <div class="attachments-list">
                  <el-link
                    v-for="file in item.attachments"
                    :key="file.id"
                    :href="file.url"
                    target="_blank"
                    class="attachment-item"
                  >
                    <Icon icon="ep:document" class="mr-1" />
                    {{ file.name }}
                    <span class="file-size">({{ formatFileSize(file.size) }})</span>
                  </el-link>
                </div>
              </div>

              <!-- 自定义内容插槽 -->
              <div class="content-custom" v-if="item.customContent">
                <component :is="item.customContent" v-bind="item.customProps" />
              </div>
            </div>

            <!-- 操作按钮 -->
            <div class="content-actions" v-if="item.actions && item.actions.length > 0">
              <el-button
                v-for="action in item.actions"
                :key="action.key"
                :type="action.type || 'primary'"
                :size="action.size || 'small'"
                :disabled="action.disabled"
                link
                @click="handleAction(action, item, index)"
              >
                <Icon v-if="action.icon" :icon="action.icon" class="mr-1" />
                {{ action.label }}
              </el-button>
            </div>
          </div>
        </div>
      </div>

      <!-- 加载更多 -->
      <div class="timeline-footer" v-if="showLoadMore">
        <el-button @click="handleLoadMore" :loading="loadingMore">
          <Icon icon="ep:refresh" class="mr-1" />
          加载更多
        </el-button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { formatDateTime } from '@/utils/formatTime'
import { formatFileSize } from '@/utils/eval'

interface TimelineAction {
  key: string
  label: string
  type?: 'primary' | 'success' | 'warning' | 'danger' | 'info'
  size?: 'large' | 'default' | 'small'
  icon?: string
  disabled?: boolean
}

interface TimelineAttachment {
  id: string | number
  name: string
  url: string
  size?: number
}

interface TimelineTag {
  name: string
  type?: 'primary' | 'success' | 'warning' | 'danger' | 'info'
}

interface TimelineItem {
  id?: string | number
  title: string
  description?: string
  time: string | Date
  type?: 'success' | 'warning' | 'danger' | 'info' | 'primary'
  icon?: string
  operator?: string
  tags?: TimelineTag[]
  attachments?: TimelineAttachment[]
  actions?: TimelineAction[]
  customContent?: any
  customProps?: Record<string, any>
}

interface Props {
  /** 时间轴标题 */
  title?: string
  /** 时间轴项目 */
  items: TimelineItem[]
  /** 是否显示加载更多 */
  showLoadMore?: boolean
  /** 是否正在加载更多 */
  loadingMore?: boolean
  /** 是否倒序显示 */
  reverse?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  showLoadMore: false,
  loadingMore: false,
  reverse: false
})

const emit = defineEmits<{
  'action-click': [action: TimelineAction, item: TimelineItem, index: number]
  'load-more': []
}>()

/** 处理操作点击 */
const handleAction = (action: TimelineAction, item: TimelineItem, index: number) => {
  emit('action-click', action, item, index)
}

/** 处理加载更多 */
const handleLoadMore = () => {
  emit('load-more')
}

/** 格式化时间 */
const formatTime = (time: string | Date) => {
  if (!time) return ''
  return formatDateTime(time)
}

/** 计算显示的项目列表 */
const displayItems = computed(() => {
  return props.reverse ? [...props.items].reverse() : props.items
})
</script>

<style scoped>
.timeline-container {
  width: 100%;
  padding: 20px;
  background: #fff;
  border-radius: 8px;
}

.timeline-header {
  margin-bottom: 20px;
  padding-bottom: 10px;
  border-bottom: 1px solid #e5e7eb;
}

.timeline-list {
  position: relative;
}

.timeline-item {
  display: flex;
  position: relative;
  margin-bottom: 20px;
}

.timeline-item:last-child {
  margin-bottom: 0;
}

.timeline-node {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-right: 20px;
  position: relative;
}

.node-dot {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  z-index: 2;
  background: #fff;
  border: 2px solid #e5e7eb;
}

.dot-success {
  border-color: #16a34a;
  background: #dcfce7;
  color: #16a34a;
}

.dot-warning {
  border-color: #f59e0b;
  background: #fef3c7;
  color: #f59e0b;
}

.dot-danger {
  border-color: #dc2626;
  background: #fef2f2;
  color: #dc2626;
}

.dot-info {
  border-color: #06b6d4;
  background: #cffafe;
  color: #06b6d4;
}

.dot-primary {
  border-color: #3b82f6;
  background: #dbeafe;
  color: #3b82f6;
}

.node-icon {
  font-size: 16px;
}

.node-default {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #9ca3af;
}

.node-line {
  width: 2px;
  height: 100%;
  background: #e5e7eb;
  position: absolute;
  top: 32px;
  left: 50%;
  transform: translateX(-50%);
  min-height: 40px;
}

.timeline-content-item {
  flex: 1;
  background: #f9fafb;
  border-radius: 8px;
  padding: 16px;
  border: 1px solid #e5e7eb;
  position: relative;
}

.timeline-content-item::before {
  content: '';
  position: absolute;
  left: -8px;
  top: 15px;
  width: 0;
  height: 0;
  border-top: 8px solid transparent;
  border-bottom: 8px solid transparent;
  border-right: 8px solid #e5e7eb;
}

.timeline-content-item::after {
  content: '';
  position: absolute;
  left: -7px;
  top: 15px;
  width: 0;
  height: 0;
  border-top: 8px solid transparent;
  border-bottom: 8px solid transparent;
  border-right: 8px solid #f9fafb;
}

.content-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 8px;
}

.content-title {
  font-weight: 600;
  font-size: 16px;
  color: #374151;
  flex: 1;
}

.content-time {
  font-size: 12px;
  color: #9ca3af;
  white-space: nowrap;
  margin-left: 10px;
}

.content-description {
  color: #6b7280;
  margin-bottom: 8px;
  line-height: 1.5;
}

.content-operator {
  display: flex;
  align-items: center;
  font-size: 12px;
  color: #9ca3af;
  margin-bottom: 8px;
}

.content-tags {
  margin-bottom: 8px;
}

.content-attachments {
  margin-bottom: 8px;
}

.attachments-title {
  display: flex;
  align-items: center;
  font-size: 12px;
  color: #6b7280;
  margin-bottom: 4px;
}

.attachments-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.attachment-item {
  display: flex;
  align-items: center;
  font-size: 12px;
}

.file-size {
  color: #9ca3af;
  margin-left: 4px;
}

.content-custom {
  margin-bottom: 8px;
}

.content-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.timeline-footer {
  text-align: center;
  margin-top: 20px;
  padding-top: 20px;
  border-top: 1px solid #e5e7eb;
}
</style>
